
const path = require('path');
const fs = require('fs/promises');
const copyDir = require('recursive-copy');
const utils = require('../utils');
const del = require('del');

const TEXT_FILES = (() => {
    const types = ['java', 'xml', 'txt', 'properties', 'factories', 'yaml', 'yml', 'pom', 'js', 'json', 'ts', 'md', 'html', 'css', 'sass', 'less', 'scss'];
    const map = {};
    types.forEach(t => map[t] = true);
    return map;
})();

exports.genSubTasks = (ctx, task) => {
    return [
        {
            task: async () => {
                ctx.namespace = await task.prompt({ type: 'Input', message: 'input the root namespace (e.g: com.ugeez.xxx): ' });
            }
        }
    ];
};

exports.process = async (ctx, task) => {

    const { project } = ctx;

    const projectName = utils.lineToCamelCase(project, true);
    const javaFolder = `${path.sep}src${path.sep}main${path.sep}java`;
    const namespace = ctx['namespace'] || '';

    const pjsMap = ctx['needProcess'] || {};
    const files = ctx['files'] || [];

    for (let { filename, filePath } of files) {
        const fstat = await fs.stat(filePath);

        if (!fstat.isDirectory()) {
            let ext = filename.substring(filename.lastIndexOf('.') + 1, filename.length);
            let strs = filename.split('.');
            let fullExt;
            if (strs.length > 2) {
                fullExt = strs[strs.length - 2] + '.' + strs[strs.length - 1];
            }
            if (ext && (TEXT_FILES[ext] || (fullExt && TEXT_FILES[fullExt]))) {
                let text = await fs.readFile(filePath, 'utf-8');
                text = text.replaceAll('$GROUP_ID', namespace);
				text = text.replaceAll('$PROJ_NAME', projectName);
				text = text.replaceAll('$PROJ', project);
                if (namespace === '') {
                    text = text.replaceAll('$NAMESPACE.', '');
                }
                text = text.replaceAll('$NAMESPACE', namespace);

                if (pjsMap[filePath]) {
                    let pjs = await require('fs/promises').readFile(filePath + '.process.js', 'utf-8');
                    await del([ filePath + '.process.js' ]);
                    
                    let pfunc;
                    eval(pjs + `; pfunc = process;`);
                    text = await pfunc({
                        ctx, text,
                        requireModule: (modPath) => {
                            return require(path.resolve(__dirname, '../', modPath));
                        }
                    });
                }

                await require('fs/promises').writeFile(filePath, text, 'utf-8');
            }
        }

        if (filename.indexOf('__PROJ_NAME__') >= 0) {
            //替换带有变量的文件名
            let realFilePath = filePath.replace('__PROJ_NAME__', projectName);
            await fs.rename(filePath, realFilePath);
        } else if (filename.indexOf('__PROJ__') >= 0) {
            //替换带有变量的文件名
            let realFilePath = filePath.replace('__PROJ__', project);
            await fs.rename(filePath, realFilePath);
        } else if (filePath.endsWith(javaFolder) && namespace !== '') {
            //根据命名空间生成目录，并移动文件到命名空间目录下
            const nsFolder = path.resolve(filePath, namespace.replace(/\./img, path.sep));
            await fs.mkdirp(nsFolder);
            await utils.lookUpDir(filePath, async (f, fp) => {
                await copyDir(fp, path.resolve(nsFolder, f));
                await del([fp]);
            });
        }
    }
}